Object-relational mapping (ORM) is a technique for converting data between different data type systems in object-oriented programming systems. The mapping effectively creates a virtual object database that can be used from within the object-oriented programming system.
In some systems, an object model expressed in an object oriented programming language is mapped to a data model of a relational database (schema or database model). Operations on the data are then conducted according to the object model. In this instance, database commands are not issued to the database. Instead, object methods are executed within the object model and values are changed within the object model. When a query is made for the relational database or changes to the data are made, those queries and changes are translated to database commands, and those commands are sent to the database.
A type (object) is the root of the object model. A type class (object) represents type declarations: class types, interface types, array types, value types, enumeration types, type parameters, generic type definitions, and open or closed constructed generic types. The members of the type class are used to get information about a type declaration, such as constructors, methods, fields, properties, and events of a class, in addition to the module and assembly in which the class is deployed.
An object model may have an entity class, class member, association, and method that map to a database model having a table, field, foreign key relationship, and stored procedure or function, respectively. In this example, a database table is represented by an entity class. A foreign key relationship defines a relationship between two database tables with a primary-key identified in a first table (or a field in the first table) and a foreign-key identified in another table (or a field or multiple fields in another table).
Entity objects (or just entities) have properties (attributes), methods (functions), and data. A property may have an accessor that contains executable statements associated with getting (reading or computing) or setting (writing) the property. Thus, an accessor is used to obtain data from the database.
Entity objects may have expressions or expression trees that represent a node in a tree-like data structure. Each node is an expression (i.e., a method call or an operation). Code represented by expression trees can be compiled, which enables dynamic modification of executable code, the execution of queries and databases, and the creation of queries.
A lambda expression is one of any number of expressions (and expression types) that is used to build an expression tree. A lambda expression is a means of defining an abstract algorithm before it is known to what data that algorithm will be applied.
An assembly is a collection of entity types and resources that are built to work together and form a logical unit of functionality. An assembly contains the information needed at run time so that the application is aware of type implementations.
The type class is the root of the reflection functionality and is the primary way to access metadata. Reflection provides objects that encapsulate assemblies, modules, and types. Reflection can be used to dynamically create an instance of a type (object), bind the type (object) to an existing object, or get the type from an existing object. The type's methods may be invoked or the fields and properties of the type may be accessed.
Some ORM systems contain classes that are used to generate an ORM object model that represents the structure and content of a relational database. These mappings are identified as namespaces. For example, a mapping namespace class (object) may designate a property to represent a database association (such as a foreign-key relationship), a field attribute (to associate a class with a field (column) and a database table), an accessor to a member, a meta-association to represent an association relationship between two entity types, a mapping between a context method and a database function, a meta-data table to represent an abstraction of a database table view, a meta-data type to represent a mapping of a domain object type to a field (column) of a database table, and other mappings.
One type of namespace is a reflection namespace. The reflection namespace contains the types that retrieve information about assemblies, modules, members, parameters, and other entities by examining their metadata. These types can also be used to manipulate instances of loaded types. For example, a namespace object represents an abstract root object for a data source. Properties can be referenced by namespaces.
A run time loader manages application domains. This management includes loading each assembly into the appropriate application domain and controlling the memory layout of the type hierarchy within each assembly. Assemblies contain modules, modules contain types, and types contain members.
Rows in a relational database table do not have unique identities. Since each row has a unique primary key, no two rows share the same key value. However, this fact constrains only the contents of the database table.
When a new row is retrieved from a database, the row is logged in an identity table by its primary key, and a new object is created. When that same row is retrieved, the original object instance is handed back to the application. Thus, the data context manages the object identity and translates the concept of identity as seen by the database (e.g., primary key) into the concept of identity accepted by the ORM (e.g., instances). The ORM application only sees the object in the state from which it was first retrieved. An identity table acts as a cache of all previously retrieved objects.
A data context provides the mapping of all object entities to the database model. It is through the data context that the application containing the object entities can query the database. It is through the data context that changes to the database can be implemented.
Data management tasks in object-oriented programming systems typically are implemented by manipulating objects that are almost always non-scalar variables. Scalar variables hold only a single value at a time, whereas non-scalar variables may hold composite variables, such as arrays, lists, hash, records, and other non-scalar variable types.
Many database systems, such as structured query language database management systems and other relational database management systems, can only store or manipulate scalar values, such as integers and strings organized within tables. Thus, ORM systems convert object values from object data structures into groups of simpler values for storage in a database and convert the database values back to object values upon retrieval. The process of retrieving data from a database and mapping the data to an ORM object is sometimes referred to as touching the object.
There are, however, problems translating the logical representation of ORM objects into a separate form capable of being stored in a relational database while also preserving properties of the ORM objects and their relationships to each other so that the ORM objects can be reloaded (e.g., so that their data can be accessed) as the object is needed. Other problems occur when mapping between ORM objects and relational databases, particularly when ORM objects are mapped in a straight-forward way to database tables or relational schemas.
Some mapping problems are referred to as object-relational competence mismatches. Mismatches include encapsulation (where object methods are hidden and cannot be accessed until provided, particularly for accessing relational database records), invariance (where invariants are not easily represented in relational databases), accessibility (where relational databases and objects and object models may have conflicts over relativity versus absolute classifications and characteristics of objects and records), mapping to relational concepts (where proper mappings between relational concepts and object-oriented concepts can be made if relational database tables are linked to associations found in objects), data type differences (scalar versus non-scalar and pointer prohibition versus pointer use), structural differences (entity objects verses relational database records), manipulative differences (the ability to manipulate the data models; whereas relational databases use primitive operators to query and manipulate data, objects query and manipulate objects through physical access at specific imperative operations), and transactional differences (the granularity of transactions in relational databases versus objects).